﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;

namespace MyDLL
{
    /// <summary>
    /// JSON工具类
    /// </summary>
    public class JsonUtility
    {
        /// <summary>
        /// 序列化对象到字符串。
        /// </summary>
        /// <param name="value"></param>
        /// <param name="isIndented">是否缩进，默认为true。</param>
        /// <param name="isIgnoreNullValue">是否忽略空值，默认为true。</param>
        /// <param name="isIgnoreMissingMember">是否缺省值，默认为true。</param>
        /// <returns>返回字符串。</returns>
        public static string SerializeObject(object value, bool isIndented = true,bool isIgnoreNullValue = true,bool isIgnoreMissingMember = true)
        {
            Formatting formatting = (isIndented) ? Formatting.Indented : Formatting.None;
            string res = string.Empty;
            JsonSerializerSettings settings = new JsonSerializerSettings
            {
                NullValueHandling = NullValueHandling.Ignore,
                MissingMemberHandling = MissingMemberHandling.Ignore
            };

            if (!isIgnoreNullValue) settings.NullValueHandling = NullValueHandling.Include;
            if (!isIgnoreMissingMember) settings.MissingMemberHandling = MissingMemberHandling.Error;

            res = JsonConvert.SerializeObject(value, formatting, settings);

            return res;
        }

        /// <summary>
        /// 序列化对象到字符串。
        /// </summary>
        /// <param name="value">待序列化对象</param>
        /// <param name="path">JSON文件路径</param>
        /// <param name="isIndented">是否缩进，默认为true。</param>
        /// <param name="isIgnoreNullValue">是否忽略空值，默认为true。</param>
        /// <param name="isIgnoreMissingMember">是否缺省值，默认为true。</param>
        /// <returns>返回字符串。</returns>
        public static void SerializeObjectToFile(object value,string path, bool isIndented = true, bool isIgnoreNullValue = true, bool isIgnoreMissingMember = true)
        {
            string jsonStr = SerializeObject(value, isIndented, isIgnoreNullValue, isIgnoreMissingMember);
            FileStream fs = null;
            StreamWriter sw = null;
            try
            {
                fs = new FileStream(path, FileMode.OpenOrCreate, FileAccess.Write);
                sw = new StreamWriter(fs);
                sw.Write(jsonStr);
            }
            finally
            {
                sw.Close();
                fs.Close();
            }
        }

        /// <summary>
        /// 序列化对象到JSON文件。
        /// </summary>
        /// <param name="value"></param>
        /// <param name="path">JSON文件的路径</param>
        /// <param name="encoding">Encoding，默认为空，即Encoding.Default。</param>
        /// <param name="isIndented">是否缩进，默认为true。</param>
        /// <param name="isIgnoreNullValue">是否忽略空值，默认为true。</param>
        /// <param name="isIgnoreMissingMember">是否缺省值，默认为true。</param>
        public static void SerializeObject(object value, string path, Encoding encoding = null, bool isIndented = true, bool isIgnoreNullValue = true, bool isIgnoreMissingMember = true)
        {
            string jsonStr = SerializeObject(value, isIndented, isIgnoreNullValue, isIgnoreMissingMember);
            if (encoding == null) encoding = Encoding.Default;
            using (StreamWriter sw = new StreamWriter(path, false, encoding)) 
            {
                sw.Write(jsonStr);
            }
        }

        /// <summary>
        /// 反序列化JSON字符串。
        /// </summary>
        /// <typeparam name="T">返回结果的类型</typeparam>
        /// <param name="jsonStr">JSON字符串</param>
        /// <param name="isIgnoreNullValue">是否忽略空值，默认为true。</param>
        /// <param name="isIgnoreMissingMember">是否缺省值，默认为true。</param>
        /// <returns></returns>
        public static T DeserializeObject_FromString<T>(string jsonStr, bool isIgnoreNullValue = true, bool isIgnoreMissingMember = true)
        {
            T res;
            JsonSerializerSettings settings = new JsonSerializerSettings
            {
                NullValueHandling = NullValueHandling.Ignore,
                MissingMemberHandling = MissingMemberHandling.Ignore
            };

            if (!isIgnoreNullValue) settings.NullValueHandling = NullValueHandling.Include;
            if (!isIgnoreMissingMember) settings.MissingMemberHandling = MissingMemberHandling.Error;

            res = JsonConvert.DeserializeObject<T>(jsonStr, settings);
            return res;
        }

        /// <summary>
        /// 反序列化JSON字符串。
        /// </summary>
        /// <typeparam name="T">返回结果的类型</typeparam>
        /// <param name="path">JSON文件的完整路径</param>
        /// <param name="encoding">Encoding，默认为空，即Encoding.Default。</param>
        /// <param name="isIgnoreNullValue">是否忽略空值，默认为true。</param>
        /// <param name="isIgnoreMissingMember">是否缺省值，默认为true。</param>
        /// <returns></returns>
        public static T DeserializeObject_FromFile<T>(string path, Encoding encoding = null, bool isIgnoreNullValue = true, bool isIgnoreMissingMember = true)
        {
            if (encoding == null) encoding = Encoding.Default;
            string jsonStr = string.Empty;
            using (StreamReader sr = new StreamReader(path, encoding))
            {
                jsonStr = sr.ReadToEnd();
            }
            return DeserializeObject_FromString<T>(jsonStr, isIgnoreNullValue, isIgnoreMissingMember);
        }

        /// <summary>
        /// 反序列化JSON字符串。
        /// </summary>
        /// <typeparam name="T">返回结果的类型</typeparam>
        /// <param name="stream">JSON文件读入Stream</param>
        /// <param name="isIgnoreNullValue">是否忽略空值，默认为true。</param>
        /// <param name="isIgnoreMissingMember">是否缺省值，默认为true。</param>
        /// <returns></returns>
        public static T DeserializeObject_FromStream<T>(Stream stream, bool isIgnoreNullValue = true, bool isIgnoreMissingMember = true)
        {
            string jsonStr = string.Empty;
            using (StreamReader sr = new StreamReader(stream))
            {
                jsonStr = sr.ReadToEnd();
            }
            return DeserializeObject_FromString<T>(jsonStr, isIgnoreNullValue, isIgnoreMissingMember);
        }
    }
}
